package com.ht.api.callback.impl;

import java.util.List;

import javax.sql.DataSource;

import com.ht.api.callback.CallbackFunction;
import com.ht.api.constant.CacheConstants;
import com.ht.api.db.Db;
import com.ht.api.db.DbConfig;
import com.ht.api.db.Entity;
import com.ht.api.db.util.RedisUtil;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 回调函数：基类
 * @author asq
 * @createTime 2025年1月17日 13:26:47
 */
@Slf4j
public abstract class BaseCallbackFunction implements CallbackFunction{
	/** 应用ID */
	protected String appid;
	
	@Override
	public void execute(String appid, Entity callback, JSONObject params) {
		// 保存appid，供子类使用
		this.appid = appid;
		
		// open_data表的source_code字段值
		String sourceCode = getSourceCode(callback, params);
		
        // 调用接口
		List<String> str = buildSourceDataList(params);
		
		// 写入租户库的open_data表
		if (str != null && !str.isEmpty()) {
			str.stream().forEach(data -> {
				if (StrUtil.isNotBlank(data)) {
					Db.insert(getTenantDs(appid), createOpenDataEntity(appid, sourceCode, data));
				}
			});
		}
	}
	
	/**
	 * 创建需要写入open_data表的data字符串列表
	 * @param params 收到的回调数据
	 * @return
	 */
	protected abstract List<String> buildSourceDataList(JSONObject params);
	
	/**
	 * 指定open_data表的source_code字段值
	 * @param callback open_callback表数据
	 * @param params 收到的回调json数据
	 * @return
	 */
	protected String getSourceCode(Entity callback, JSONObject params) {
		return callback.getMainId();
	}

	/**
	 * 获取接口配置
	 * @param apiId 应用ID
	 * @return
	 */
	protected JSONObject getApiConfig(long apiId) {
		Entity entity = RedisUtil.get(CacheConstants.KEY_API + apiId);
		return JSONUtil.parseObj(entity.getStr("config"));
	}

	/**
	 * 返回应用的所属租户库数据源
	 * @param appId
	 * @return
	 */
	protected DataSource getTenantDs(String appId) {
		Entity entity = RedisUtil.get(CacheConstants.KEY_APP + appId);
		return DbConfig.useTenantDb(entity.getLong("tenant_id"));
	}

	/**
	 * 根据接口返回数据，创建一个要插入open_data表的Entity
	 * @param sourceCode open_data表的source_code字段值
	 * @param resultString 接口返回的json数据
	 * @return
	 */
	private Entity createOpenDataEntity(String appId, String sourceCode, String resultString) {
		JSONObject bean = JSONUtil.parseObj(resultString);
		bean.set("appid", appId);
		return Entity.create("open_data").set("source_code", sourceCode).set("data", JSONUtil.toJsonStr(bean));
	}
}
